/**
 * Copyright (C) 2006-2012 phloc systems
 * http://www.phloc.com
 * office[at]phloc[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phloc.genericode;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import org.genericode._2006.ns.codelist._0.Column;
import org.genericode._2006.ns.codelist._0.ColumnRef;
import org.genericode._2006.ns.codelist._0.ColumnSet;
import org.genericode._2006.ns.codelist._0.Key;
import org.genericode._2006.ns.codelist._0.KeyColumnRef;
import org.genericode._2006.ns.codelist._0.Row;
import org.genericode._2006.ns.codelist._0.SimpleValue;
import org.genericode._2006.ns.codelist._0.Value;

import com.phloc.commons.annotations.ReturnsMutableCopy;

/**
 * Helper class for Genericode 0.4 reading
 * 
 * @author philip
 */
@Immutable
public final class Genericode04Utils
{
  private Genericode04Utils ()
  {}

  @Nonnull
  public static String getColumnElementID (final Object aColumnElement)
  {
    if (aColumnElement instanceof ColumnRef)
      return ((ColumnRef) aColumnElement).getId ();
    if (aColumnElement instanceof Column)
      return ((Column) aColumnElement).getId ();
    throw new IllegalArgumentException ();
  }

  @Nullable
  public static String getRowValue (@Nonnull final Row aRow, @Nonnull final String sColumnID)
  {
    for (final Value aValue : aRow.getValue ())
    {
      final String sID = getColumnElementID (aValue.getColumnRef ());
      if (sID.equals (sColumnID))
      {
        final SimpleValue aSimpleValue = aValue.getSimpleValue ();
        return aSimpleValue != null ? aSimpleValue.getValue () : null;
      }
    }
    return null;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List <String> getAllColumnIDs (@Nonnull final ColumnSet aColumnSet)
  {
    final List <String> ret = new ArrayList <String> ();
    for (final Object o : aColumnSet.getColumnChoice ())
      if (o instanceof Column)
        ret.add (((Column) o).getId ());
    return ret;
  }

  @Nullable
  public static Column getColumnOfID (@Nonnull final ColumnSet aColumnSet, @Nullable final String sID)
  {
    if (sID != null)
      for (final Object o : aColumnSet.getColumnChoice ())
        if (o instanceof Column)
          if (((Column) o).getId ().equals (sID))
            return (Column) o;
    return null;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List <String> getAllKeyIDs (@Nonnull final ColumnSet aColumnSet)
  {
    final List <String> ret = new ArrayList <String> ();
    for (final Object o : aColumnSet.getKeyChoice ())
      if (o instanceof Key)
        ret.add (((Key) o).getId ());
    return ret;
  }

  @Nullable
  public static Key getKeyOfID (@Nonnull final ColumnSet aColumnSet, @Nullable final String sID)
  {
    if (sID != null)
      for (final Object o : aColumnSet.getKeyChoice ())
        if (o instanceof Key)
          if (((Key) o).getId ().equals (sID))
            return (Key) o;
    return null;
  }

  public static boolean isKeyColumn (@Nonnull final ColumnSet aColumnSet, @Nonnull final String sColumnID)
  {
    for (final Object o : aColumnSet.getKeyChoice ())
      if (o instanceof Key)
        for (final KeyColumnRef aColumnRef : ((Key) o).getColumnRef ())
          if (aColumnRef.getRef () instanceof Column)
          {
            if (((Column) aColumnRef.getRef ()).getId ().equals (sColumnID))
              return true;
          }
    return false;
  }
}
